#include"heapsort.h"
#include<cstdio>
#include<cstdlib>
#include "../stream/inputbufferstream.h"
#include "../stream/outputbufferstream.h"

void heapclass::heapPrint(char* filename)
{
	int i;

	outputbufferstream os;
	os.create(filename);

	for(i=1;i<=(position);i++)
		os.write_s(heapspace[i]);
	os.close_s();
}


int heapclass::SWAP( int* a, int* b)
{
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
	return 0;
}

int heapclass::heapIntialize( int space )
{
	this->heapspace = new int [space+1];
	if(heapspace == NULL)
		return 0;
	else
	{
		return 1;
	}
}

void heapclass::heapClean()
{
	delete this->heapspace;
}


int heapclass::heapIsEmpty()
{
	if(position != 0)
		return 0;
	else if (position == 0)
		return 1;
}

int heapclass::heapInsert(int data)
{
	this->position = this->position+1;
	//std::cout << "value of position : " << position << std::endl ;
	heapspace[position] = data;
	fixHeapUp(position);
}

int heapclass::heapRemoveMax()
{
	int local=position;
	SWAP(this->heapspace+1,this->heapspace+(position));
	fixHeapDown(heapspace,1,position-1);
	this->position = this->position -1;
	return heapspace[local];
}

void heapclass::heapSortInterface()
{
heapSort(heapspace,1,position);
}

void heapclass::heapSort(int * heapSpace , int left , int right )
{
	int i;
	int size = right - left + 1;
	for(i=size/2;i>=1;i--)
	{
		fixHeapDown(heapSpace+left-1,i, size);
	}
	while(size>1)
	{
		SWAP(heapSpace+left,heapSpace+size-1+left);
		fixHeapDown(heapSpace+left-1,1,--size);
	}
}

int heapclass::fixHeapUp(int position )
{
	while((position)>1 && (heapspace[(position)/2]<heapspace[(position)]))
	{
		SWAP(this->heapspace+(position)/2,this->heapspace+(position));
		(position) = (position)/2;
	}
}

int heapclass::fixHeapDown(int * heapSpace , int pos , int position)
{
	int i;
	while(2*pos<=position)
	{
		i = 2*pos;
		if(i< position && (heapSpace[i]<heapSpace[i+1]))
			i++;
		if((heapSpace[pos]>heapSpace[i]))
			break;
		SWAP(heapSpace+pos,heapSpace+i);
		pos= i;
	}
}



int main(int argc, char *argv[])
{
	if(argc!=3)
	{
		std::cout << "usage is : " << argv[0] << " filename [num]" << std::endl;
		exit(0);
	}

	inputbufferstream is;
	is.open_s(argv[1]);
	int num = atoi(argv[2]);
	heapclass d;
	if(!d.heapIntialize(num))
	{
		std::cout << "failed to allocate memory";
	}
	for(int i=0;i<num;i++)
	{
		int a;
		a = is.read_next();
		if(a != EOF)
			d.heapInsert(a);
		else
			break;
	}
	is.close_i();
	d.heapSortInterface();
	d.heapPrint("out");

}

